package com.sinosoft.utils.logback;

import com.alibaba.fastjson.JSONArray;
//import com.alibaba.fastjson.JSONObject;
//import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
//
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import javax.servlet.http.HttpSession;
//import java.lang.reflect.Method;
//import java.util.Map;


@Aspect
@Component
public class LogAspect {
//
//	private static SimplePropertyPreFilter simplePropertyPreFilter;
//
//	/**
//	 * 排除参数输出
//	 *
//	 * @return
//	 */
//	private static SimplePropertyPreFilter getExcludes() {
//		if (simplePropertyPreFilter == null) {
//			simplePropertyPreFilter = new SimplePropertyPreFilter();
//			// JSON的KEY
//			simplePropertyPreFilter.getExcludes().add("byteArray");
//			simplePropertyPreFilter.getExcludes().add("encodeBase64");
//		}
//		return simplePropertyPreFilter;
//	}
//
//	private static final String excludesClass = ",DownLoadFilePAppServiceImpl,SubmitFilePAppServiceImpl";
//
//	/**controller中方法
//	 * @param point
//	 * @return
//	 * @throws Throwable
//	 * @author zouren
//	 */
//	@Around("execution(* com.taikang.controller.*.*(..))")
//	public Object doCtrlSystemLog(ProceedingJoinPoint point) throws Throwable {
//		long startTime = beforeMethod(false, point);
//		Object obj = point.proceed();
//		afterMethod(false, point,startTime,obj);
//		return obj;
//	}
//
	/**service 中方法 除了 get与set方法 子项目不能切入
	 * @param point
	 * @return
	 * @throws Throwable
	 * @author zouren
	 */
//	@Around("(execution(* com.taikang.service..*(..))) or (execution(* com.taikang.comm..*(..))) or (execution(* com.taikang.appService..*(..)))")
	@Around("(execution(* com.sinosoft.*.service..*(..))) or (execution(* com.sinosoft.*.service.impl.*(..)))")	
        public Object doServiceSystemLog(ProceedingJoinPoint point) throws Throwable {
		long beginTime = beforeMethod(false, point);
		Object obj = point.proceed();
		afterMethod(false, point,beginTime,obj);
		return obj;
	}

	/**方法执行之前 调用
	 * @param isMoveGetSet 是否不监控get 与 set 开头的方法
	 * @param point
	 * @throws Throwable
	 * @author zouren
	 */
	private long beforeMethod(boolean isMoveGetSet, ProceedingJoinPoint point)
			throws Throwable {
		Class<?> targetClass = point.getTarget().getClass();
		String methodName = point.getSignature().getName();
                long re = System.currentTimeMillis();
                
		//String[] param =formatArgs(point);
		Object[] param = point.getArgs();
		//LogUtil.process("id:{} {} method:{} start time:{}",re, targetClass.getName(),methodName,re);
		//LogUtil.process("{} method:{} param: {}", targetClass.getName(),methodName, JSONArray.toJSONString(param, getExcludes()).replaceAll("\\\\", ""));
		LogUtil.process("id:{} method:{} param:{}", targetClass.getName(),methodName, JSONArray.toJSONString(param));                
		return re;
	}

	/**方法执行之后 调用
	 * @param isMoveGetSet 是否不监控get 与 set 开头的方法
	 * @param point
	 * @param beginTime 开始时间
	 * @param obj 返回值
	 * @throws Throwable
	 */
	private void afterMethod(boolean isMoveGetSet, ProceedingJoinPoint point, long beginTime, Object obj)
			throws Throwable {
		Class<?> targetClass = point.getTarget().getClass();
		String methodName = point.getSignature().getName();
		long endTime=System.currentTimeMillis();
                
//		if(excludesClass.indexOf(targetClass.getSimpleName())>=0){
//			obj="";
//		}
		//LogUtil.process("id:{} {} method:{} endtime:{} 耗时:{}ms re {}",beginTime, targetClass.getName(),methodName,endTime,endTime-beginTime, JSONObject.toJSONString(obj, getExcludes()).replaceAll("\\\\", ""));
                LogUtil.process("id:{} method:{} 耗时:{}", targetClass.getName(),methodName, endTime-beginTime);
	}
//
//	 /**
//     * 格式化方法请求参数
//     *
//     * @param joinPoint 方法
//     * @return 存放有处理结果的数组
//     */
//    private String[] formatArgs(ProceedingJoinPoint joinPoint) {
//    	  MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
//         Method method = methodSignature.getMethod();//方法
//         Class<?>[] argClasses = method.getParameterTypes();//参数类型数组
//         int len =  method.getParameterCount();
//        String[] re = new String[len];//用来保存格式化后的参数的数组
//        if (len >= 1) {
//        	Class<?> argClass = null;
//        	Object[] args = joinPoint.getArgs();
//        	Object arg = null;
//            for (int i = 0; i < len; i++) {
//            	argClass = argClasses[i];
//            	arg = args[i];
//                if (HttpServletRequest.class.equals(argClass)) {
//                	 re[i] = formatHttpServletRequest((HttpServletRequest) arg, i);//格式化HttpServletRequest类型的参数
//                } else if (HttpServletResponse.class.equals(argClass)) {
//                	 re[i] = formatHttpServletResponse((HttpServletResponse) arg, i);//格式化HttpServletResponse类型的参数
//                } else if (HttpSession.class.equals(argClass)) {
//                	 re[i] = formatHttpSession((HttpSession) arg, i);//格式化HttpSession类型的参数
//                } else if("access".equals(method.getName())||"accessValidate".equals(method.getName())){
//                	String name = joinPoint.getTarget().getClass().getSimpleName();
//                		re[i] = formatAppAccess(excludesClass.indexOf(name)==-1,arg, i, argClass);//格式化其他类型的参数
//                }else{
//                	 re[i] = formatOther(arg, i, argClass);//格式化其他类型的参数
//                }
//            }
//        }
//        return re;
//    }
//
//    /**对APP服务日志打印
//     * @param isPring 是否打印
//     * @param obj
//     * @param index
//     * @param argClass
//     * @return
//     */
//    private String formatAppAccess(boolean isPring,Object obj, int index, Class<?> argClass) {
//        String logStr;
//        if (obj != null&&isPring) {
//        	String argJson = JSONObject.toJSONString(obj, getExcludes());
//            logStr = String.format("参数%d | 类型:%s | 值:%s", index, argClass.getName(), argJson);
//        } else {
//            logStr = String.format("参数%d | 类型:%s | 参数为空", index, HttpServletRequest.class.getName());
//        }
//        return logStr;
//    }
//	/**
//     * 格式化HttpServletRequest类型的参数
//     *
//     * @param request HttpServletRequest实例
//     * @param index   参数的位置
//     */
//    private String formatHttpServletRequest(HttpServletRequest request, int index) {
//        String logStr;
//        if (request != null) {
//            Map<String, String[]> parameterMap = request.getParameterMap();
//            String parameterMapStr = JSONObject.toJSONString(parameterMap, getExcludes());
//            String userAgentStr = request.getHeader("user-agent");
//            logStr = String.format("参数%d | 类型:%s | parameterMap:%s | user-agent:%s", index, HttpServletRequest.class.getName(), parameterMapStr, userAgentStr);
//        } else {
//            logStr = String.format("参数%d | 类型:%s | 参数为空", index, HttpServletRequest.class.getName());
//        }
//        return logStr;
//    }
//
//    /**
//     * 格式化HttpServletResponse类型的参数
//     *
//     * @param response HttpServletResponse实例
//     * @param index    参数的位置
//     */
//    private String formatHttpServletResponse(HttpServletResponse response, int index) {
//        String logStr;
//        if (response != null) {
//            int status = response.getStatus();
//            logStr = String.format("参数%d | 类型:%s | status:%d", index, HttpServletResponse.class.getName(), status);
//        } else {
//            logStr = String.format("参数%d | 类型:%s | 参数为空", index, HttpServletRequest.class.getName());
//        }
//        return logStr;
//    }
//
//    /**
//     * 格式化HttpSession类型的参数
//     *
//     * @param session HttpSession实例
//     * @param index   参数的位置
//     */
//    private String formatHttpSession(HttpSession session, int index) {
//        String logStr;
//        if (session != null) {
//            String sessionId = session.getId();
//            logStr = String.format("参数%d | 类型:%s | sessionId:%s", index, HttpSession.class.getName(), sessionId);
//        } else {
//            logStr = String.format("参数%d | 类型:%s | 参数为空", index, HttpServletRequest.class.getName());
//        }
//        return logStr;
//    }
//
//    /**
//     * 格式化其他类型的参数
//     *
//     * @param obj      参数
//     * @param index    参数的位置
//     * @param argClass 参数类
//     */
//    private String formatOther(Object obj, int index, Class<?> argClass) {
//        String logStr;
//        if (obj != null) {
//        	String argJson = JSONObject.toJSONString(obj, getExcludes());
//            logStr = String.format("参数%d | 类型:%s | 值:%s", index, argClass.getName(), argJson);
//        } else {
//            logStr = String.format("参数%d | 类型:%s | 参数为空", index, HttpServletRequest.class.getName());
//        }
//        return logStr;
//    }
//
//	public static void main(String[] args) {
//		JSONObject a = new JSONObject();
//		JSONObject test = new JSONObject();
//		test.put("a", "asdfsd");
//		JSONArray array = new JSONArray();
//		array.add(test);
//		a.put("date", test);
//		a.put("date1", array);
//		System.out.println(JSONObject.toJSONString(a));
//		System.out.println(JSONObject.toJSONString(a, getExcludes()));
//	}
}
